package com.cheer.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.lang.UUID;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import com.cheer.dto.ResourceDTO;
import com.cheer.entity.LecCourseEntity;
import com.cheer.enums.ResourceEnum;
import com.cheer.exception.ServiceException;
import com.cheer.param.ResourceParam;
import com.cheer.service.LecResourceService;
import com.cheer.vo.FileVO;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.concurrent.BasicThreadFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;

import java.io.File;
import java.io.IOException;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.stream.Collectors;

@Service
@Slf4j
public class LecResourceServiceImpl implements LecResourceService {

    @Value("${resource.base_path}")
    private String resource;

    @Value("${resource.temporary}")
    private String temporary;

    @Value("${resource.base_path_url}")
    private String basePathUrl;

    @Override
    public String upload(@Validated ResourceParam resourceParam) {

        // 1. 检查文件类型和文件是否相符
        ResourceEnum resourceEnum = ResourceEnum.getByTypeCode(resourceParam.getType());
        if(resourceParam.getFile() == null){
            throw new ServiceException("请上传文件！");
        }
        if(resourceEnum == null){
            throw new ServiceException("请上传指定文件类型！");
        }
        String fileName = resourceParam.getFile().getOriginalFilename();
        String fileExt = FileUtil.extName(fileName);
        if(StrUtil.isNotBlank(resourceEnum.getFileType()) && resourceEnum.getFileType().contains(fileExt) == false){
            throw new ServiceException("请上传指定文件类型！");
        }
        String fileNewName = UUID.randomUUID().toString(true)+"."+fileExt;
        String fileStorePath = resourceEnum.filePath(resource, fileNewName);
        try {
            FileUtil.touch(fileStorePath);
            resourceParam.getFile().transferTo(new File(fileStorePath));
        } catch (IOException e) {
            log.error("上传文件异常", e);
            throw new ServiceException("图片上传异常");
        }

        return fileNewName;
    }

    @Override
    public List<FileVO> getFileVOs(String fileStr, ResourceEnum resourceEnum) {

        if(StrUtil.isBlank(fileStr)){
            return null;
        }
        List<ResourceDTO> fileDTOs = getFileDTOs(fileStr, resourceEnum);
        List<FileVO> fileVOS = BeanUtil.copyToList(fileDTOs, FileVO.class);

        return fileVOS;
    }

    public List<ResourceDTO> getFileDTOs(String fileStr, ResourceEnum resourceEnum) {

        List<String> split = StrUtil.split(fileStr, ",");
        List<ResourceDTO> list = split.stream().map(url -> {
            ResourceDTO fileDTO = new ResourceDTO();
            fileDTO.setShortUrl(url);
            fileDTO.setDiskUrl(resource + resourceEnum.getPathName() +File.separator + url);
            fileDTO.setFullUrl(basePathUrl + resourceEnum.getPathName() +File.separator + url);
            return fileDTO;
        }).collect(Collectors.toList());

        return list;
    }



    @Override
    public String getTempLecFile(List<LecCourseEntity> list) {

        String temporaryDir = temporary + RandomUtil.randomNumbers(32) + File.separator;
        FileUtil.mkdir(temporaryDir);
        ScheduledThreadPoolExecutor executor = new ScheduledThreadPoolExecutor(3,
                new BasicThreadFactory.Builder().namingPattern("schedule-pool-%d").daemon(true).build());
        for (int i = 0; i < list.size(); i++) {

            LecCourseEntity lecCourseEntity = list.get(i);
            // 演讲文件夹名称
            String title = (i+1)+"."+ FileUtil.cleanInvalid(lecCourseEntity.getTitle());
            String pathTemplate = temporaryDir  + "讲座信息" + File.separator + title + File.separator + "{}" + File.separator ;
            executor.execute(()->copyFilesToTarget(pathTemplate, lecCourseEntity.getImage(), "佐证图片", ResourceEnum.IMAGE));
            executor.execute(()->copyFilesToTarget(pathTemplate, lecCourseEntity.getLectureFile(), "讲稿", ResourceEnum.DOC));
            executor.execute(()->copyFilesToTarget(pathTemplate, lecCourseEntity.getVitae(), "讲师简历", ResourceEnum.DOC));
            executor.execute(()->copyFilesToTarget(pathTemplate, lecCourseEntity.getMaterial(), "其他", ResourceEnum.OTHER));
        }
        executor.shutdown();
        return temporaryDir;
    }

    /**
     * 复制文件到初始文件路径下
     * @param pathTemplate
     * @param files
     * @param folder
     * @param resourceEnum
     */
    private void copyFilesToTarget(String pathTemplate, String files,
                                   String folder, ResourceEnum resourceEnum) {
        if(StrUtil.isBlank(files)){
            return;
        }
        String pathImage = pathTemplate.replace("{}", folder);
        List<ResourceDTO> fileDTOs = getFileDTOs(files, resourceEnum);
        fileDTOs.forEach( fileDTO -> {
            String diskPath = fileDTO.getDiskUrl();
            FileUtil.touch(diskPath);
            String targetPath = pathImage + File.separator + fileDTO.getShortUrl();
            FileUtil.copy(diskPath, targetPath, true);
        });

    }


}
